<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">

<html>
<head>
    <title>Using Wrapper Functions</title>
</head>

<body>
    <div class="Section1">
        <h1>Using Wrapper Functions</h1>

        <p>The propose of this document is to provide an example of
        how to use wrapper functions to create programs that are
        more robust and that Splint can check more
        effectively.&nbsp; The C standard library function realloc
        has complex semantics and is easy to use incorrectly.&nbsp;
        Still, it is a popular function, and we are frequently
        asked how to use Splint to check code that uses
        realloc.&nbsp; We hope to answer these questions in this
        section.&nbsp; Additionally, we hope this example will
        provide insight into other ways to work around some of the
        limitations of Splint&rsquo;s checking, and serve as a
        template for users wishing to create their own wrapper
        functions.</p>

        <p>Splint cannot currently describe general functions where
        some of the attributes are dependent on one or more of the
        possible return values.&nbsp; Often, functions are defined
        to modify their outputs, and perhaps allocate storage, but
        can also return an error indication, in which case none of
        the modifications or allocations will take place.</p>

        <p>One very common example of this is the C standard
        library function realloc( void *pointer, size_t
        size).&nbsp; When realloc succeeds, the pointer passed to
        it is no longer valid.&nbsp; The returned pointer points to
        available storage with the specified size, and the values
        are copied from the leading portion of the original storage
        indicated by the pointer passed to the function.&nbsp; When
        realloc returns a NULL pointer, and more than zero bytes
        were supposed to be allocated, no new storage has been
        allocated.&nbsp; The original pointer passed in is not
        deallocated and its contents are still accessible.&nbsp;
        (Under ANSI C '89 and later, malloc and realloc may return
        NULL if asked for zero bytes.&nbsp; In this case, realloc
        would release the old storage.)</p>

        <p>If you use realloc, -usereleased can be used to suppress
        warnings.&nbsp; However, this may result in legitimate
        warnings for other errors being suppressed as well.&nbsp;
        If you don't mind crafting your code to work around
        Splint's quirks, you can isolate this difficult-to-describe
        behavior to a single function that's easy to verify by
        inspection, and use that function elsewhere.&nbsp; For
        example:</p>

        &nbsp;&nbsp;&nbsp; /*@-usereleased@*/<br>

        &nbsp;&nbsp;&nbsp; static /*@null@*/ void *<br>

        &nbsp;&nbsp;&nbsp; grow_or_free (/*@only@*/ void *ptr,
        size_t newsize)<br>

        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        /*@*/<br>

        &nbsp;&nbsp;&nbsp; {<br>

        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void
        *newptr;<br>

        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newptr =
        realloc (ptr, newsize);<br>

        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (newptr ==
        NULL &amp;&amp; newsize != 0) {<br>

        
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        /* Splint would complain,<br>

        
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        but this is correct.&nbsp; */<br>

        
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        free (ptr);<br>

        
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        return NULL;<br>

        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>

        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return
        newptr;<br>

        &nbsp;&nbsp;&nbsp; }<br>

        &nbsp;&nbsp;&nbsp; /*@=usereleased@*/<br>

        <p>It would also be possible to use a function that always
        returns a valid pointer, and separately indicates whether
        it managed to change the size to that desired by the
        caller.</p>
    </div>
</body>
</html>
